﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Imaging;

namespace MedVis
{
    public partial class MainWindow : Window
    {
        public static WriteableBitmap createImage1(String src1, string src2)
        {
            BitmapImage bmp = new BitmapImage(new Uri(src1));
            BitmapImage bmp2 = new BitmapImage(new Uri(src2));
            WriteableBitmap wbmp = BitmapFactory.ConvertToPbgra32Format(new WriteableBitmap(bmp));
            WriteableBitmap wbmp2 = BitmapFactory.ConvertToPbgra32Format(new WriteableBitmap(bmp2));
            WriteableBitmap wbmp3 = new WriteableBitmap(wbmp.PixelWidth, wbmp.PixelHeight, wbmp.DpiX, wbmp.DpiY, wbmp.Format, wbmp.Palette);

            wbmp.Lock();
            wbmp2.Lock();
            wbmp3.Lock();
            byte[] b1 = wbmp.ToByteArray();
            byte[] b2 = wbmp2.ToByteArray();
            byte[] b3 = wbmp3.ToByteArray();
            for (int i = 0; i < b3.Length; i++)
            {
                b3[i] = (byte)((b1[i] + b2[i]) / 2);
            }
            wbmp.Unlock();
            wbmp2.Unlock();
            wbmp3.Unlock();
            wbmp3 = BitmapFactory.New(wbmp.PixelWidth, wbmp.PixelHeight).FromByteArray(b3);

            return wbmp3;
        }

        private void export3DTest(object s, DoWorkEventArgs args)
        {
            string filename = (string)args.Argument;
            if (iS.getAllImages().Count == 0) return;
            FileStream datei = new FileStream(filename, FileMode.Create);
            WriteableBitmap wbmp = new WriteableBitmap(new BitmapImage(new Uri(iS.getImage(0).path)));
            uint dimx = (uint)(wbmp.PixelWidth - iS.cropLeft - iS.cropRight);
            uint dimy = (uint)(wbmp.PixelHeight - iS.cropBot - iS.cropTop);
            uint dimz = (uint)(iS.getAllImages().Count);
            uint dimt = 1;

            double sizex = iS.stackWidth;
            double sizey = iS.stackHeight;
            double sizez = (double)dimz * iS.sliceThickness;
            double sizet = 1;

            datei.Write(BitConverter.GetBytes(dimx), 0, 4);
            datei.Write(BitConverter.GetBytes(dimy), 0, 4);
            datei.Write(BitConverter.GetBytes(dimz), 0, 4);
            datei.Write(BitConverter.GetBytes(dimt), 0, 4);

            datei.Write(BitConverter.GetBytes(sizex), 0, 8);
            datei.Write(BitConverter.GetBytes(sizey), 0, 8);
            datei.Write(BitConverter.GetBytes(sizez), 0, 8);
            datei.Write(BitConverter.GetBytes(sizet), 0, 8);

            ushort nrOfBytes = 2;

            datei.Write(BitConverter.GetBytes(nrOfBytes), 0, 2);

            string format = "VM_VOLUME_PHOTO_RGB_555                                                                                                                                                                              & nbsp;                                                                                                                                                             ";

            System.Text.ASCIIEncoding enc = new System.Text.ASCIIEncoding();

            datei.Write(enc.GetBytes(format), 0, 128);

            double[] transMat = new double[16];
            transMat[0] = 1;
            transMat[1] = 0;
            transMat[2] = 0;
            transMat[3] = 0;

            transMat[4] = 0;
            transMat[5] = 1;
            transMat[6] = 0;
            transMat[7] = 0;

            transMat[8] = 0;
            transMat[9] = 0;
            transMat[10] = 1;
            transMat[11] = 0;

            transMat[12] = 0;
            transMat[13] = 0;
            transMat[14] = 0;
            transMat[15] = 1;

            for (int i = 0; i < 16; i++)
            {
                datei.Write(BitConverter.GetBytes(transMat[i]), 0, 8);
            }
            byte[] dummyLut = { 0, 0, 0, 0, 0, 0 };
            datei.Write(dummyLut, 0, 6);
            //WriteableBitmap wbmp;
            byte[] voxel;
            List<byte> voxelList = new List<byte>();
            for (int i = 0; i < iS.getAllImages().Count; i++)
            {
                MyImageObject mio = iS.getImage(i);
                wbmp = BitmapFactory.ConvertToPbgra32Format(new WriteableBitmap(new BitmapImage(new Uri(mio.path))));

                if (iS.cropBot != 0 || iS.cropLeft != 0 || iS.cropRight != 0 || iS.cropTop != 0 || mio.rota != 0 || mio.offsetX != 0 || mio.offsetY != 0)
                {
                    wbmp = editImage(wbmp, mio);
                }

                wbmp.Lock();
                System.Windows.Media.Color mediacolor1;
                for (int row = 0; row < wbmp.PixelHeight; row++)
                {
                    for (int col = 0; col < wbmp.PixelWidth; col++)
                    {
                        mediacolor1 = wbmp.GetPixel(col, row);
                        BitArray bitsR = new BitArray(new byte[] { (byte)(mediacolor1.R / 8) });
                        BitArray bitsG = new BitArray(new byte[] { (byte)(mediacolor1.G / 8) });
                        BitArray bitsB = new BitArray(new byte[] { (byte)(mediacolor1.B / 8) });


                        //farben falsch!!!
                        BitArray bitsColorNew = new BitArray(16);
                        //rot
                        bitsColorNew.Set(0, bitsR.Get(0));
                        bitsColorNew.Set(1, bitsR.Get(1));
                        bitsColorNew.Set(2, bitsR.Get(2));
                        bitsColorNew.Set(3, bitsR.Get(3));
                        bitsColorNew.Set(4, bitsR.Get(4));
                        //gruen
                        bitsColorNew.Set(5, bitsG.Get(0));
                        bitsColorNew.Set(6, bitsG.Get(1));
                        bitsColorNew.Set(7, bitsG.Get(2));
                        bitsColorNew.Set(8, bitsG.Get(3));
                        bitsColorNew.Set(9, bitsG.Get(4));
                        //blau
                        bitsColorNew.Set(10, bitsB.Get(0));
                        bitsColorNew.Set(11, bitsB.Get(1));
                        bitsColorNew.Set(12, bitsB.Get(2));
                        bitsColorNew.Set(13, bitsB.Get(3));
                        bitsColorNew.Set(14, bitsB.Get(4));

                        bitsColorNew.Set(15, false);


                        //bits zu bytes
                        voxel = new byte[bitsColorNew.Length / 8];
                        bitsColorNew.CopyTo(voxel, 0);
                        voxelList.Add(voxel[0]);
                        voxelList.Add(voxel[1]);
                    }
                }
                wbmp.Unlock();
                voxel = voxelList.ToArray();
                datei.Write(voxel, 0, voxel.Length);
                voxelList.Clear();
                worker.ReportProgress(i + 1);
            }
            datei.Close(); 
            MessageBoxResult result = System.Windows.MessageBox.Show("Export complete", "Export", MessageBoxButton.OK, MessageBoxImage.Information);

            worker.ReportProgress(0);
        }
        
        public WriteableBitmap editImage(WriteableBitmap wbmp, MyImageObject mio)
        {//bilder bearbeiten
            //double widthFactor = ImageSize.X / wbmp.PixelWidth;
            //double heightFactor = ImageSize.Y / wbmp.PixelHeight;
            double widthFactor = iS.stackWidth / wbmp.PixelWidth * 25.4;
            double heightFactor = iS.stackHeight / wbmp.PixelHeight * 25.4;
            scalefactorX = wbmp.PixelWidth / ImageSize.X;
            scalefactorY = wbmp.PixelHeight / ImageSize.Y;
            if (mio.rota != 0)
            {
                wbmp = wbmp.RotateFree(mio.rota, true);
            }
            if (mio.offsetX != 0 || mio.offsetY != 0)
            {
                WriteableBitmap hwbmp = BitmapFactory.ConvertToPbgra32Format(new WriteableBitmap(wbmp.PixelWidth, wbmp.PixelHeight, wbmp.DpiX, wbmp.DpiY, wbmp.Format, wbmp.Palette));
                hwbmp.Clear(System.Windows.Media.Color.FromArgb(0, 255, 255, 255));
                Rect r1 = new Rect(0, 0, wbmp.PixelWidth, wbmp.PixelHeight);
                Rect r2 = new Rect(0, 0, wbmp.PixelWidth, wbmp.PixelHeight);
                double x = mio.offsetX * 96 / 25.4 * scalefactorX;//widthFactor;
                double y = mio.offsetY * 96 / 25.4 * scalefactorY;//heightFactor;
                //links
                if (x > 0 && y == 0)
                {
                    r1 = new Rect(0, 0, Convert.ToInt32(wbmp.PixelWidth - x), Convert.ToInt32(wbmp.PixelHeight));
                    r2 = new Rect(Convert.ToInt32(x), 0, Convert.ToInt32(wbmp.PixelWidth - x), Convert.ToInt32(wbmp.PixelHeight));
                }
                //oben
                if (x == 0 && y > 0)
                {
                    r1 = new Rect(0, 0, Convert.ToInt32(wbmp.PixelWidth), Convert.ToInt32(wbmp.PixelHeight - y));
                    r2 = new Rect(0, Convert.ToInt32(y), Convert.ToInt32(wbmp.PixelWidth), Convert.ToInt32(wbmp.PixelHeight - y));
                }
                //rects
                if (x < 0 && y == 0)
                {
                    r1 = new Rect(Convert.ToInt32(Math.Abs(x)), 0, Convert.ToInt32(wbmp.PixelWidth - Math.Abs(x)), Convert.ToInt32(wbmp.PixelHeight));
                    r2 = new Rect(0, 0, Convert.ToInt32(wbmp.PixelWidth - Math.Abs(x)), Convert.ToInt32(wbmp.PixelHeight));
                }
                //unten
                if (x == 0 && y < 0)
                {
                    r1 = new Rect(0, Convert.ToInt32(Math.Abs(y)), Convert.ToInt32(wbmp.PixelWidth), Convert.ToInt32(wbmp.PixelHeight - Math.Abs(y)));
                    r2 = new Rect(0, 0, Convert.ToInt32(wbmp.PixelWidth), Convert.ToInt32(wbmp.PixelHeight - Math.Abs(y)));
                }
                //links oben
                if (x > 0 && y > 0)
                {
                    r1 = new Rect(0, 0, Convert.ToInt32(wbmp.PixelWidth - x), Convert.ToInt32(wbmp.PixelHeight - y));
                    r2 = new Rect(x, y, Convert.ToInt32(wbmp.PixelWidth - x), Convert.ToInt32(wbmp.PixelHeight - y));
                }
                //links unten
                if (x > 0 && y < 0)
                {
                    r1 = new Rect(0, Math.Abs(y), Convert.ToInt32(wbmp.PixelWidth - x), Convert.ToInt32(wbmp.PixelHeight - Math.Abs(y)));
                    r2 = new Rect(x, 0, Convert.ToInt32(wbmp.PixelWidth - x), Convert.ToInt32(wbmp.PixelHeight - Math.Abs(y)));
                }
                //rechts oben
                if (x < 0 && y > 0)
                {
                    r1 = new Rect(Math.Abs(x), 0, Convert.ToInt32(wbmp.PixelWidth - Math.Abs(x)), Convert.ToInt32(wbmp.PixelHeight - y));
                    r2 = new Rect(0, y, Convert.ToInt32(wbmp.PixelWidth - Math.Abs(x)), Convert.ToInt32(wbmp.PixelHeight - y));
                }
                //rechts unten
                if (x < 0 && y < 0)
                {
                    r1 = new Rect(Math.Abs(x), Math.Abs(y), Convert.ToInt32(wbmp.PixelWidth - Math.Abs(x)), Convert.ToInt32(wbmp.PixelHeight - Math.Abs(y)));
                    r2 = new Rect(0, 0, Convert.ToInt32(wbmp.PixelWidth - Math.Abs(x)), Convert.ToInt32(wbmp.PixelHeight - Math.Abs(y)));
                }
                hwbmp.Blit(r2, wbmp, r1);
                wbmp = hwbmp;
            }
            double t, l, b, r = 0;
            t = iS.cropTop * 96 / 25.4;
            l = iS.cropLeft * 96 / 25.4;
            b = iS.cropBot * 96 / 25.4;
            r = iS.cropRight * 96 / 25.4;
            if (iS.cropTop != 0 || iS.cropRight != 0 || iS.cropLeft != 0 || iS.cropBot != 0)
            {
                wbmp = wbmp.Crop(Convert.ToInt32(l), Convert.ToInt32(t), Convert.ToInt32(wbmp.PixelWidth - r - l), Convert.ToInt32(wbmp.PixelHeight - b - t));
            }
            return wbmp;
        }

        private void toPng(string filename, WriteableBitmap wbmp)
        {
            using (FileStream stream5 = new FileStream(filename, FileMode.Create))
            {
                PngBitmapEncoder encoder5 = new PngBitmapEncoder();
                encoder5.Frames.Add(BitmapFrame.Create(wbmp));
                encoder5.Save(stream5);
                stream5.Close();
            }
        }

    }
}
